﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using EMailClient;

namespace RISMOTAXDP.EmailService.MailTransfer
{
    public class MailSender : IDisposable
    {

        /// <summary>
        /// 获取待发送查询语句
        /// </summary>
        private const string SQL_SELECT_MAIL =
@"select 
MQ.Mail_ID,
MQ.OperationCode,
vwSMTPRoute_List.MailFrom,
MQ.MailRcpt,
MQ.MailSubject,
MQ.MailContent,
MQ.MailCreateDate
from TBL_MailQueueProcess as MQ
left join vwSMTPRoute_List
on MQ.OperationCode = vwSMTPRoute_List.OperationCode
where MailStatus = 0";

        /// <summary>
        /// 更新邮件发送成功查询语句
        /// </summary>
        private const string SQL_UPDATE_SUCCESS = @" UPDATE TBL_MailQueueProcess set MailStatus = 1, MailSendDateTime =  CONVERT(VARCHAR(19),GETDATE(),120) where Mail_ID =@MailID ";
        /// <summary>
        /// 更新邮件发送失败查询语句
        /// </summary>
        private const string SQL_UPDATE_FAUILED = @" UPDATE TBL_MailQueueProcess set MailStatus = 2 where Mail_ID =@MailID ";
        /// <summary>
        /// 更新邮件重新创建语句
        /// </summary>
        private const string SQL_UPDATE_RECREAT = @" UPDATE TBL_MailQueueProcess set MailStatus = 3 where Mail_ID =@MailID ";


        /// <summary>
        /// 当次待发送邮件列表
        /// </summary>
        private Dictionary<MailServerInfo, List<EMail>> m_SendList;

        /// <summary>
        /// SMTP邮件服务器客户端
        /// </summary>
        private ISMTPHandler m_SMTPClient;

        /// <summary>
        /// 获取当前正在使用的SMTP邮件服务器客户端
        /// </summary>
        public ISMTPHandler SMTPClient
        {
            get { return m_SMTPClient; }
        }

        /// <summary>
        /// SMTP邮件服务器信息
        /// </summary>
        private MailServerInfo m_ServerInfo;

        /// <summary>
        /// 初始化
        /// </summary>
        public MailSender()
        {
            m_SendList = new Dictionary<MailServerInfo, List<EMail>>();
        }



        /// <summary>
        /// 连接到SMTP邮件服务器
        /// </summary>
        /// <param name="serverInfo">邮件服务器信息</param>
        /// <returns>返回连接是否成功</returns>
        public bool Connect(MailServerInfo serverInfo)
        {
            m_ServerInfo = serverInfo;

            m_SMTPClient = new SMTPClient(serverInfo.MailSMTPServerAddr, serverInfo.MailServerUser, serverInfo.MailServerPwd);
            try
            {
                return m_SMTPClient.Connect() && m_SMTPClient.AuthLogin();
            }
            catch { return false; }

        }



        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            if (m_SMTPClient != null)
            {

                    m_SMTPClient.Close();
    
            }
            m_ServerInfo = null;
        }


        /// <summary>
        /// 检查待发送邮件
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="mailList">服务器列表</param>
        public void CheckData(SqlConnection conn, MailServerInfoList mailList)
        {
            m_SendList.Clear();
            //读取系统中所有待发送的邮件

            using (SqlDataReader reader_Mail = SQLHelper.ExecuteReader(conn, CommandType.Text, SQL_SELECT_MAIL))
            { 
                EMail newMail = null;
                while (reader_Mail.Read())
                {
                    string mailID = reader_Mail[0].ToString();
                    string operationCode = reader_Mail.GetString(1);
                    newMail = new EMail();
                    newMail.Id = mailID;
                    newMail.From = reader_Mail.GetString(2);
                    newMail.To = reader_Mail.GetString(3);
                    newMail.Subject = reader_Mail.GetString(4);
                    newMail.Body = reader_Mail.GetString(5);
                    newMail.BodyHTML = reader_Mail.GetString(5);
                    newMail.IsBodyHtml = true;
                    AddMailToSendList(mailList[operationCode], newMail);
                    
                }
            }
 

        }

        /// <summary>
        /// 将邮件添加到发送队列
        /// </summary>
        /// <param name="serverInfo">服务器信息</param>
        /// <param name="newMail">新邮件</param>
        private void AddMailToSendList(MailServerInfo serverInfo, EMail newMail)
        {
            if (serverInfo == null || newMail == null) return;
            bool mailAdd = false;
            foreach (MailServerInfo serverKey in m_SendList.Keys)
            {
                if (serverKey.EqualSMTP(serverInfo))
                {
                    m_SendList[serverKey].Add(newMail);
                    mailAdd = true;
                    break;
                }
            }
            if (!mailAdd)
            {
                m_SendList.Add(serverInfo, new List<EMail>());
                m_SendList[serverInfo].Add(newMail);
            }
        }


        /// <summary>
        /// 返回指定邮件是否可以发送
        /// </summary>
        /// <returns></returns>
        public bool IsNextMailReady()
        {
            EMail mail = m_SendList[m_ServerInfo][0];
            //检查邮件附件是否存在
            /*
            for (int i = 0; i < mail.Attachments.Count; i++)
            {
                if (!System.IO.File.Exists(mail.Attachments[i].FilePath)) //不存在时返回发送失败
                    return false;
            }
             */
            return true;
        }


        /// <summary>
        /// 发送指定邮件
        /// </summary>
        /// <param name="index">邮件索引</param>
        /// <returns>返回发送结果</returns>
        public bool SendNextMail()
        {
            try
            {
                if (!m_SMTPClient.Reset()) return false;
                return m_SMTPClient.SendMail(m_SendList[m_ServerInfo][0], true);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 设置邮件发送结果
        /// </summary>
        /// <param name="conn">数据库连接</param>
        /// <param name="sendState">状态</param>
        public void SendMailResult(SqlConnection conn, SendStatus sendState)
        {
            EMail mail = m_SendList[m_ServerInfo][0];
            try
            {
                m_SendList[m_ServerInfo].RemoveAt(0);

                SqlParameter[] sParms = { new SqlParameter("@MailId", mail.Id) };
               
                switch (sendState)
                {
                    case SendStatus.Success:
                        SQLHelper.ExecuteNonQuery(conn, System.Data.CommandType.Text, SQL_UPDATE_SUCCESS, sParms);
                        break;
                    case SendStatus.Fauiled:
                        SQLHelper.ExecuteNonQuery(conn, System.Data.CommandType.Text, SQL_UPDATE_FAUILED, sParms);
                        break;
                    case SendStatus.ReCreate:
                        SQLHelper.ExecuteNonQuery(conn, System.Data.CommandType.Text, SQL_UPDATE_RECREAT, sParms);
                        break;
                }
            }
            catch (Exception exception)
            {
                GlobalObject.WriteOperationLog("E84000004", exception, mail.Id);
            }
        }


        /// <summary>
        /// 返回待发送邮件的服务器列表
        /// </summary>
        public ICollection<MailServerInfo> ServerList
        {
            get { return m_SendList.Keys; }
        }

        /// <summary>
        /// 获取向该SMTP邮件服务器发送的邮件总数
        /// </summary>
        /// <returns>返回邮件总数</returns>
        public int GetMailCount(MailServerInfo serverInfo)
        {
            return m_SendList[serverInfo].Count;
        }



        #region IDisposable 成员
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            m_SendList.Clear();
        }
        #endregion

        /// <summary>
        /// 邮件发送结果
        /// </summary>
        public enum SendStatus
        {
            /// <summary>
            /// 发送成功
            /// </summary>
            Success,
            /// <summary>
            /// 发送失败
            /// </summary>
            Fauiled,
            /// <summary>
            /// 该邮件需要重新创建
            /// </summary>
            ReCreate
        }



    }
}
